# -*- coding: utf-8 -*-
import os, urllib, time
import xbmc, xbmcgui, xbmcaddon, xbmcplugin
from copy import deepcopy

import sqlite3, math
import threading

try:
    import json
    print 'JSON'
except:
    import demjson3 as json
    print 'DEMIJSON3'

try:
    from hashlib import md5 as md5
except:
    import md5

from GenreSelect        import GenreSelectDialog
from CountrySelect      import CountrySelectDialog
import RussianKeyboard

KEY_BUTTON_BACK = 275
KEY_KEYBOARD_ESC = 61467

SERIAL_LIST     = 201
SERIAL_NUM      = 100

SEASON_LIST     = 301
MOVIE_LIST      = 401

def lower_str(s):
    return s.lower()

class MainScreen(xbmcgui.WindowXML):
  def __init__(self, *args, **kwargs):
    xbmcgui.WindowXML.__init__(self)
    self.Auth = kwargs.get('Auth')
    self.icon = xbmc.translatePath(os.path.join(self.Auth.Addon_path, r'icon.png'))
    #---
    self.mode = 'Serial'
    self.country = ''
    self.genre = ''
    self.search = ''
    self.focus  = SERIAL_LIST
    self.list = []
    self.isStart = True

  def __del__(self):
    try:
        self.conn.close()
    except:
        pass

  def f_md5(self, str):
    try:
        rez = md5(str)
    except:
        rez = md5.md5(str)
    return rez

  def onInit(self):
    xbmcgui.WindowXML.onInit(self)
    self.win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
    self.version = '[B][COLOR=FF33CC00]ver. '+self.Auth.Addon.getAddonInfo('version')+'[/COLOR][/B]'
    self.getControl(900).setLabel(self.version)
    self.getControl(141).setLabel('<<')
    self.getControl(142).setLabel('>>')
    self.getControl(144).setLabel('<')
    self.getControl(145).setLabel('>')

    if self.isStart == True:
         #-- load serial list
        self.page = 1
        self.win.setProperty('Page', 'First')
        self.win.setProperty('onUp', '140')
        #-- check if local DB should be used
        self.local_db       = self.Auth.Addon.getSetting('local_db')
        self.auto_update    = self.Auth.Addon.getSetting('auto_update')
        #-- if local db is used
        if self.local_db == 'true':
            self.conn = sqlite3.connect(xbmc.translatePath(os.path.join(self.Auth.Addon_path, r'seasonvar_ru.db3')))
            self.conn.create_function("lower", 1, lower_str)

        #-- if Auto Update is enabled - run update
        if self.local_db == 'true' and self.auto_update == 'true':
            self.thread = threading.Thread(target = self.Update_DB)
            self.thread.setDaemon(True)
            self.thread.start()

        #-- check if page should be used
        self.use_page  = self.Auth.Addon.getSetting('use_page')
        self.win.setProperty('is_Page', self.use_page)
        self.page_size = int(self.Auth.Addon.getSetting('page_size'))
        #-- initially reload list of serials
        self.Reload_Serial()
        self.isStart = False

  def onClick(self, controlId):
    currentControl = self.getControl(controlId)
    #-- main menu -----------------------------------
    if controlId == 131 or controlId == 132: #-- Exit
      if self.mode == 'Season':
            currentControl.setLabel('Выход')
            self.mode = 'Serial'
            self.win.setProperty('Mode', self.mode)
            xbmc.sleep(500)
            self.win.setFocusId(131)
      elif self.mode == 'Movie':
            self.mode = 'Season'
            self.win.setProperty('Mode', self.mode)
            xbmc.sleep(500)
            self.win.setFocusId(SEASON_LIST)
      else:
        self.close()

    if controlId == 121: #-- Genre
      self.genre_changed = False
      try:
          kwargs={'MainScreen': self}
          aw = GenreSelectDialog('tvp_genreDialog.xml', self.Auth.Addon.getAddonInfo('path'), **kwargs)
          aw.doModal()
          del aw

          if self.genre_changed == True:
            self.page = 1
            self.focus = controlId
            self.Reload_Serial()
      except:
        pass

    if controlId == 122: #-- Country
      self.country_changed = False
      try:
          kwargs={'MainScreen': self}
          aw = CountrySelectDialog('tvp_countryDialog.xml', self.Auth.Addon.getAddonInfo('path'), **kwargs)
          aw.doModal()
          del aw

          if self.country_changed == True:
            self.page = 1
            self.focus = controlId
            self.Reload_Serial()
      except:
        pass

    if controlId == 151: #-- Search by serial name
      try:

          kb = RussianKeyboard.Keyboard(self.Auth.Addon, self.search, 'Поиск по имени сериала')
          kb.doModal()
          if kb.isConfirmed():
            text = kb.getText()
            #--
            self.page = 1
            self.search = text
            self.focus = controlId
            if self.search== '':
                self.getControl(151).setLabel('...')
            else:
                self.getControl(151).setLabel(self.search)
            self.Reload_Serial()
      except:
        pass

    #-- page control ----------------------------------
    if controlId == 141: #-- previous page -10
      try:
          if self.page-10 < 1:
            self.page = 1
          else:
            self.page = self.page-10
          if self.page == 1:
            self.win.setProperty('Page', 'First')
          else:
            self.win.setProperty('Page', 'Between')
          self.focus = controlId
          self.Reload_Serial()
      except:
        pass

    if controlId == 144: #-- previous page
      try:
          self.page = self.page-1
          if self.page == 1:
            self.win.setProperty('Page', 'First')
          else:
            self.win.setProperty('Page', 'Between')
          self.focus = controlId
          self.Reload_Serial()
      except:
        pass

    if controlId == 145: #-- next page
      try:
          self.page = self.page+1
          if self.page == self.max_page:
            self.win.setProperty('Page', 'Last')
          else:
            self.win.setProperty('Page', 'Between')
          self.focus = controlId
          self.Reload_Serial()
      except:
        pass

    if controlId == 142: #-- next page +10
      try:
          if self.page+10 > self.max_page:
            self.page = self.max_page
          else:
            self.page = self.page+10

          if self.page == self.max_page:
            self.win.setProperty('Page', 'Last')
          else:
            self.win.setProperty('Page', 'Between')
          self.focus = controlId
          self.Reload_Serial()
      except:
        pass

    #-- serial list -----------------------------------
    if controlId == 201:
        self.serial_name = currentControl.getSelectedItem().getProperty('serial_name')
        self.mode = 'Season'
        self.getControl(131).setLabel('Назад')
        self.getControl(132).setLabel('Назад')
        #-- load season list
        self.Reload_Season()

    #-- season list -----------------------------------
    if controlId == 301:
        self.season_id = currentControl.getSelectedItem().getProperty('season_id')
        self.mode = 'Movie'
        self.getControl(131).setLabel('Назад')
        self.getControl(132).setLabel('Назад')
        #-- load movie list
        self.Reload_Movie()

    #-- movie list -----------------------------------
    if controlId == 401:
        self.PLAY()

  def onAction(self, action):
    if action == 10:
        if self.mode == 'Season':
            self.getControl(131).setLabel('Выход')
            self.getControl(132).setLabel('Выход')
            self.mode = 'Serial'
            self.win.setProperty('Mode', self.mode)
            xbmc.sleep(500)
            self.win.setFocusId(131)
            return
        elif self.mode == 'Movie':
            self.mode = 'Season'
            self.win.setProperty('Mode', self.mode)
            xbmc.sleep(500)
            self.win.setFocusId(SEASON_LIST)
            return
    xbmcgui.WindowXML.onAction(self, action)

  #----- Serial ----------------------------------------------------------------
  def Reload_Serial(self):
    self.st = time.time()
     #-- load serial list
    serial_list = self.getControl(SERIAL_LIST)
    serial_list.reset()
    #---
    self.win.setProperty('Mode', u'Loader')
    xbmc.sleep(500)
    #---
    (list, serial_count) = self.getSerialData()
    #-- set number of found serials
    self.max_page = int(math.ceil(serial_count*1.0/self.page_size))
    if self.max_page <= 1:
        self.win.setProperty('Max_Page', 'false')
    else:
        self.win.setProperty('Max_Page', 'true')

    self.getControl(SERIAL_NUM).setLabel('[COLOR=FF33CC00]'+str(serial_count)+'[/COLOR]')
    self.getControl(143).setLabel('[COLOR=FF809AAD]'+str(self.page)+'/'+str(self.max_page)+'[/COLOR]')
    #-- set serial list
    for rec in list:
        name = rec['name']
        item = xbmcgui.ListItem(name, thumbnailImage = rec['img'])
        item.setInfo(type='video', infoLabels={ 'plot':        rec['descr']})

        label2=[]
        if len(rec['name_orig']) > 0:
          label2.append(rec['name_orig'])
        if len(rec['country']) > 0:
          label2.append(u'[COLOR=66FFFFFF]Страна:[/COLOR] %s' % rec['country'])
        if len(rec['genre']) > 0:
          label2.append(u'[COLOR=66FFFFFF]Жанр:[/COLOR] %s' % rec['genre'])
        if rec['count_of_seasons'] > 0:
          label2.append(u'[COLOR=66FFFFFF]Кол-во сезонов:[/COLOR] %s' % str(rec['count_of_seasons']))
        item.setLabel2(u'[CR]'.join(label2))

        #item.setProperty('watch_started', 'True')
        item.setProperty('serial_name', rec['name'])
        serial_list.addItem(item)
    #---
    self.win.setProperty('Mode', self.mode)
    xbmc.sleep(500)
    self.win.setFocusId(self.focus)

  def getSerialData(self):
    list = []
    serial_count = 0

    if self.local_db == 'true':
        cur = self.conn.cursor()

        #-- get list of serials
        sql = "SELECT * FROM serial"

        sql_where = ''
        if self.country <> '' or self.genre <> '' or self.search <> '':
            sql_where = sql_where + ' WHERE '
            #-- set country
            if self.country <> '':
                sql_where = sql_where + ' country LIKE "%'+ self.country + '%"'
                if self.genre <> '':
                    sql_where = sql_where + ' AND '
            #-- set genre
            if self.genre <> '':
                sql_where = sql_where + ' genre LIKE "%'+ self.genre + '%"'
            #-- set search by name
            if self.search <> '':
                sql_where = sql_where + ' lower(name) LIKE "%'+ self.search.lower() + '%"'

        sql = sql + sql_where + ' ORDER BY name'

        if self.use_page == 'true':
            sql = sql + " LIMIT " + str((self.page-1)*self.page_size) + "," + str(self.page_size)
        cur.execute(sql)
        for rec in cur.fetchall():
            list.append({'name': rec[0], 'img': rec[1], 'descr': rec[2], 'country': rec[3], 'genre': rec[4], 'name_orig': rec[5], 'count_of_seasons': rec[6]})
            #  name text, img text, descr text, country text, genre text, name_orig text, count_of_seasons

        #-- get serial count
        cur.execute("SELECT COUNT(*) FROM serial"+ sql_where)
        serial_count = cur.fetchone()[0]
    else:
        api_key =self.Auth.API_key
        #--
        url = 'http://api.seasonvar.ru/'
        #-- set country
        country = []
        if self.country <> '':
            country.append(self.country)
        #-- set genre
        genre = []
        if self.genre <> '':
            genre.append(self.genre)

        values = {
                'key'           : api_key,
                'command'       : u'getSerialList',
                'country[]'     : country,
                'genre[]'       : genre,
                'lastSeasonInfo': 1
                }

        post = urllib.urlencode(values,'unicode-escape')
        html = self.Auth.get_HTML(url, post)
        data = json.loads(html)
        #-- parse data
        for rec in data:
            #-- serial name
            try:
                name = rec['name']
            except:
                name = 'N/A'

            try:
                name_orig = rec['name_original']
            except:
                name_orig = ''

            #-- serial poster
            try:
                img = rec['poster']
            except:
                img = self.icon
            #-- serial description
            try:
                descr = rec['last_season']['description']
            except:
                descr = ''

            #-- countries
            c = ''
            try:
                for cr in rec['country']:
                    c +=cr+','
                c = c[:-1]
            except:
                pass

            #-- genres
            g = ''
            try:
                for gr in rec['genre']:
                    g +=gr+','
                g = g[:-1]
            except:
                pass

            #-- number of seasons
            try:
                count_of_seasons = int(rec['count_of_seasons'])
            except:
                count_of_seasons = 0

            list.append({'name':name, 'img': img, 'descr': descr, 'country':c, 'genre': g, 'name_orig':name_orig, 'count_of_seasons':count_of_seasons})
        serial_count = len(list)

    #-- return serials list
    return list, serial_count

    #----- Serial Season -------------------------------------------------------
  def Reload_Season(self):
     #-- load season list
    season_list = self.getControl(SEASON_LIST)
    season_list.reset()
    #---
    self.win.setProperty('Mode', u'Loader')
    xbmc.sleep(500)
    #---
    list = self.getSeasonData()
    #-- set serial list
    for rec in list:
        name = rec['name']
        item = xbmcgui.ListItem(name, thumbnailImage = rec['img'])
        item.setInfo(type='video', infoLabels={ 'plot':        rec['descr']})

        label2=[]
        if len(rec['name_orig']) > 0:
          label2.append(rec['name_orig'])
        if len(rec['season_number']) > 0:
          label2.append(u'[COLOR=66FFFFFF]Сезон:[/COLOR] %s' % rec['season_number'])
        if len(rec['year']) > 0:
          label2.append(u'[COLOR=66FFFFFF]Год:[/COLOR] %s' % rec['year'])
        item.setLabel2(u'[CR]'.join(label2))

        #item.setProperty('watch_started', 'True')
        item.setProperty('season_id', rec['season_id'])
        season_list.addItem(item)
    #---
    self.win.setProperty('Mode', self.mode)
    xbmc.sleep(500)
    self.win.setFocusId(SEASON_LIST)

  def getSeasonData(self):
    api_key =self.Auth.API_key
    #--
    url = 'http://api.seasonvar.ru/'
    #-- set country

    values = {
            'key'           : api_key,
            'command'       : u'getSeasonList',
            'name'          : self.serial_name
            }

    post = urllib.urlencode(values,'unicode-escape')
    html = self.Auth.get_HTML(url, post)
    data = json.loads(html)
    #-- parse data
    list = []
    for rec in data:
        #-- serial name
        try:
            name = rec['name']
        except:
            name = 'N/A'

        try:
            name_orig = rec['name_original']
        except:
            name_orig = ''

        #-- serial poster
        try:
            img = rec['poster']
        except:
            img = self.icon
        #-- serial description
        try:
            descr = rec['description']
        except:
            descr = ''

        #-- season number
        try:
            season_number = rec['season_number']
        except:
            season_number = ''

        #-- season id
        try:
            season_id = rec['id']
        except:
            season_id = ''

        #-- season year
        try:
            season_year = rec['year']
        except:
            season_year = ''

        list.append({'name':name, 'img': img, 'descr': descr, 'year':season_year, 'season_id': season_id, 'season_number':season_number, 'name_orig':name_orig})

    #-- return season list
    return list

    #----- Serial Season Parts -------------------------------------------------
  def Reload_Movie(self):
    del self.list[:]

    #-- load movie list
    movie_list = self.getControl(MOVIE_LIST)
    movie_list.reset()
    #---
    self.win.setProperty('Mode', u'Loader')
    xbmc.sleep(500)
    #---
    list = self.getMovieData()
    #-- set serial list
    for rec in list:
        name = rec['name']
        if len(rec['name_orig'])>0:
            name = name + ' - ' + rec['name_orig']
        name = name + ' (' + rec['season_number'] + u' сезон)'
        self.getControl(413).setLabel(name)

        for mov in rec['movie']:
            item = xbmcgui.ListItem(mov['movie_name'], thumbnailImage = rec['img'])
            item.setProperty('url', mov['url'])
            item.setProperty('img', rec['img'])

            item.setInfo(type='video', infoLabels={ 'plot':        rec['descr']})
            #item.setProperty('watched', 'True')

            movie_list.addItem(item)

            #-- add new item to the list
            self.list.append({'name': mov['movie_name'], 'url': mov['url'], 'img': rec['img']})
    #---
    self.win.setProperty('Mode', self.mode)
    xbmc.sleep(500)
    self.win.setFocusId(MOVIE_LIST)


  def getMovieData(self):
    api_key =self.Auth.API_key
    #--
    url = 'http://api.seasonvar.ru/'
    #-- set country

    values = {
            'key'           : api_key,
            'command'       : u'getSeason',
            'season_id'     : self.season_id
            }

    post = urllib.urlencode(values,'unicode-escape')
    html = self.Auth.get_HTML(url, post)
    rec = json.loads(html)
    #-- parse data
    list = []

    #-- serial name
    try:
        name = rec['name']
    except:
        name = 'N/A'

    try:
        name_orig = rec['name_original']
    except:
        name_orig = ''

    #-- serial poster
    try:
        img = rec['poster']
    except:
        img = self.icon
    #-- serial description
    try:
        descr = rec['description']
    except:
        descr = ''

    #-- season number
    try:
        season_number = rec['season_number']
    except:
        season_number = ''

    movie_list = []
    for mov in rec['playlist']:
        #-- movie name
        try:
            movie_name = mov['name']
        except:
            movie_name = ''
        #-- movie url
        try:
            url = mov['link']
        except:
            url = ''
        movie_list.append({'movie_name': movie_name, 'url': url})

    list.append({'name':name, 'img': img, 'descr': descr, 'season_number':season_number, 'name_orig':name_orig, 'movie': movie_list})

    #-- return movie list
    return list

  #-------------------------------------------------------------------------------

  def PLAY(self):
        name        = self.getControl(413).getLabel()
        list        = self.getControl(MOVIE_LIST)
        selected    = list.getSelectedItem()

        # create play list
        pl=xbmc.PlayList(1)
        pl.clear()

        # -- if requested continious play
        if self.Auth.Addon.getSetting('continue_play') == 'true':
            # -- get play list
            is_found = False

            for item in self.list:
                #-- add item to play list
                if selected.getLabel() == item['name'].encode('utf-8'):
                    is_found = True

                if is_found == True:
                    i = xbmcgui.ListItem(name+' '+item['name'].encode('utf-8'), path = urllib.unquote(item['url']), thumbnailImage=item['img'])
                    i.setProperty('IsPlayable', 'true')
                    pl.add(urllib.unquote(item['url']), i)
        # -- play only selected item
        else:
            i = xbmcgui.ListItem(name+' '+selected.getLabel(), path = urllib.unquote(selected.getProperty('url')), thumbnailImage=selected.getProperty('img'))
            i.setProperty('IsPlayable', 'true')
            pl.add( urllib.unquote(selected.getProperty('url')), i)

        #--- show video
        #try:
        kwargs={'playlist':pl, 'name': name}
        self.Auth.Player(**kwargs)
        self.Reload_Movie()
        #except:
        #    pass

  #-- autoupdate local database ------------------------------------------------
  def Update_DB(self):
        xbmc.executebuiltin('Notification(SEASONVAR.ru,%s,2000,%s)'%('Начато обновление локальной базы', os.path.join(self.Auth.Addon.getAddonInfo('path'), 'start.png')))

        conn = sqlite3.connect(xbmc.translatePath(os.path.join(self.Auth.Addon_path, r'seasonvar_ru.db3')))
        cur = conn.cursor()

        #-- get list of all serials
        api_key =self.Auth.API_key
        url = 'http://api.seasonvar.ru/'
        country = []
        genre = []

        values = {
                    'key'           : api_key,
                    'command'       : u'getSerialList',
                    'country[]'     : country,
                    'genre[]'       : genre,
                    'lastSeasonInfo': 1
                 }

        post = urllib.urlencode(values,'unicode-escape')
        html = self.Auth.get_HTML(url, post)
        list = json.loads(html)

        #-- update local database
        for rec in list:
            #-- serial name
            try:
                name = rec['name']
            except:
                name = 'N/A'

            hash = self.f_md5((name).encode('utf-8')).hexdigest()

            #-- check if serial already exists
            sql = 'SELECT count(*) FROM serial WHERE id="'+hash+'"'
            cur.execute(sql)
            if cur.fetchone()[0] == 0:  #-- serial does not found
                print '***   '+name.encode('utf-8')
                try:
                    name_orig = rec['name_original']
                except:
                    name_orig = ''

                #-- serial poster
                try:
                    img = rec['poster']
                except:
                    img = self.icon
                #-- serial description
                try:
                    descr = rec['last_season']['description']
                except:
                    descr = ''

                #-- countries
                c = ''
                try:
                    for cr in rec['country']:
                        c +=cr+','
                    c = c[:-1]
                except:
                    pass

                #-- genres
                g = ''
                try:
                    for gr in rec['genre']:
                        g +=gr+','
                    g = g[:-1]
                except:
                    pass

                #-- number of seasons
                try:
                    count_of_seasons = rec['count_of_seasons']
                except:
                    count_of_seasons = '1'

                #------------------------------
                cur.execute("INSERT INTO serial VALUES (?,?,?,?,?,?,?,?)", (name, img, descr, c, g, name_orig, count_of_seasons, hash))
                conn.commit()

        conn.close()
        xbmc.executebuiltin('Notification(SEASONVAR.ru,%s,2000,%s)'%('Завершено обновление локальной базы', os.path.join(self.Auth.Addon.getAddonInfo('path'), 'stop.png')))
